////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//	MathVector.cpp
//  MathLib
//
//  Created by Gregory Maks on 8/14/09.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "Math.h"
#include <stdio.h>
#include <math.h>



//================== Vector4 =====================
void Vector4::ctor ()
{
	x = y = z = 0;
	w = 1;
}

Vector4::Vector4 ()
{
	ctor();
}

Vector4::Vector4 (floatType _x, floatType _y, floatType _z, floatType _w)
{
	x = _x;
	y = _y;
	z = _z;
	w = _w;
}

void Vector4::AddVector (Vector4 &vec)
{
	x += vec.x;
	y += vec.y;
	z += vec.z;
}

void Vector4::SubVector (Vector4 &vec)
{
	x -= vec.x;
	y -= vec.y;
	z -= vec.z;
}

void Vector4::MultByScalar (floatType scalar)
{
	x *= scalar;
	y *= scalar;
	z *= scalar;
}

Vector4 Vector4::CrossProduct (Vector4 &vec)
{
	floatType _x = this->y * vec.z - this->z * vec.y;
	floatType _y = this->z * vec.x - this->x * vec.z;
	floatType _z = this->x * vec.y - this->y * vec.x;

	return Vector4(_x, _y, _z);
}

floatType Vector4::DotProduct (Vector4 &vec)
{
	return (this->x * vec.x + this->y * vec.y + this->z * vec.z);
}

void Vector4::Normalize ()
{
	floatType len = sqrt(x*x + y*y + z*z);
	x /= len;
	y /= len;
	z /= len;
}

floatType Vector4::Length ()
{
	return sqrt(x*x + y*y + z*z);
}

floatType Vector4::LengthSq ()
{
	return (x*x + y*y + z*z);
}

void Vector4::Transform (Matrix4x4 &mat)
{
	Vector4 tempVec;
	
	tempVec.x = x * mat.n[0][0] + y * mat.n[1][0] + z * mat.n[2][0] + w * mat.n[3][0];
	tempVec.y = x * mat.n[0][1] + y * mat.n[1][1] + z * mat.n[2][1] + w * mat.n[3][1];
	tempVec.z = x * mat.n[0][2] + y * mat.n[1][2] + z * mat.n[2][2] + w * mat.n[3][2];	
	tempVec.w = x * mat.n[0][3] + y * mat.n[1][3] + z * mat.n[2][3] + w * mat.n[3][3];	
	
	*this = tempVec;
}

void Vector4::Printf()
{
	printf("Vector4 - x:%.2f  y:%.2f  z:%.2f  w:%.2f\n", x, y, z, w);
}

Vector4 Vector4::operator+ (Vector4 &vec)
{
	return Vector4(x + vec.x, y + vec.y, z + vec.z);
}

Vector4& Vector4::operator+= (Vector4 &vec)
{
	x += vec.x;	y += vec.y; z += vec.z;
	return *this;
}

Vector4 Vector4::operator- (Vector4 &vec)
{
	return Vector4(x - vec.x, y - vec.y, z - vec.z);
}

Vector4& Vector4::operator-= (Vector4 &vec)
{
	x -= vec.x;	y -= vec.y; z -= vec.z;
	return *this;
}

floatType Vector4::operator* (Vector4 &vec)	//dot-product
{
	return DotProduct(vec);
}

Vector4 Vector4::operator* (floatType val)
{
	return Vector4(x*val, y*val, z*val);
}

Vector4& Vector4::operator*= (floatType val)
{
	x *= val; y *= val; z *= val;
	return *this;
}

Vector4 Vector4::operator* (Matrix4x4 &mat)
{
	Vector4 tempVec;
	
	tempVec.x = x * mat.n[0][0] + y * mat.n[1][0] + z * mat.n[2][0] + w * mat.n[3][0];
	tempVec.y = x * mat.n[0][1] + y * mat.n[1][1] + z * mat.n[2][1] + w * mat.n[3][1];
	tempVec.z = x * mat.n[0][2] + y * mat.n[1][2] + z * mat.n[2][2] + w * mat.n[3][2];	
	tempVec.w = x * mat.n[0][3] + y * mat.n[1][3] + z * mat.n[2][3] + w * mat.n[3][3];	
	
	return tempVec;
}

Vector4& Vector4::operator*= (Matrix4x4 &mat)
{
	Transform(mat);
	return *this;
}

Vector4 Vector4::operator^ (Vector4 &vec)	//cross-product
{
	return CrossProduct(vec);
}

Vector4& Vector4::operator^= (Vector4 &vec)	//cross-product
{
	floatType _x = this->y * vec.z - this->z * vec.y;
	floatType _y = this->z * vec.x - this->x * vec.z;
	floatType _z = this->x * vec.y - this->y * vec.x;
	
	x = _x;	y = _y;	z = _z;
	w = 1;

	return *this;
}

bool Vector4::operator== (Vector4 &vec)
{
	return (x == vec.x && y == vec.y && z == vec.z && w == vec.w);
}

bool Vector4::operator!= (Vector4 &vec)
{
	return !(*this == vec);
}


















